print("main.py 主流程已启动")
import argparse
import sys
import os
import datetime
import json
from parser import parse_slide, log_print
from exporter import export_images, export_texts, export_tables, export_layout, chinese_naming
from docgen import generate_core_md

# 新增：全局日志文件
LOG_FILE = os.path.join('output', 'run.log')

def log_print(*args, **kwargs):
    msg = ' '.join(str(a) for a in args)
    print(msg, **kwargs)
    try:
        with open(LOG_FILE, 'a', encoding='utf-8') as f:
            f.write(msg + '\n')
    except Exception as e:
        print(f'[日志写入失败] {e}')


def check_venv():
    if sys.prefix == sys.base_prefix:
        print("[警告] 当前未激活虚拟环境，建议先激活 venv 以保证依赖隔离。")


def get_pptx_page_count(pptx_path):
    from pptx import Presentation
    try:
        prs = Presentation(pptx_path)
        return len(prs.slides)
    except Exception as e:
        print(f"[错误] 无法读取PPTX文件: {e}")
        sys.exit(1)


def ask_slide_index(page_count):
    while True:
        user_input = input(f"请输入要解析的幻灯片页码（1-{page_count}）：")
        if not user_input.isdigit():
            print("[提示] 请输入数字页码。")
            continue
        idx = int(user_input)
        if 1 <= idx <= page_count:
            return idx - 1
        else:
            print(f"[提示] 页码超出范围，当前PPT共{page_count}页。")


def make_unique_output_dir(base_dir, pptx_path, slide_num):
    base_name = os.path.splitext(os.path.basename(pptx_path))[0]
    now = datetime.datetime.now().strftime('%m%d%H%M')
    unique_dir = f"{base_name}_第{slide_num}页_{now}"
    out_dir = os.path.join(base_dir, unique_dir)
    os.makedirs(out_dir, exist_ok=True)
    return out_dir


def main():
    check_venv()
    # 清空旧日志
    try:
        with open(LOG_FILE, 'w', encoding='utf-8') as f:
            f.write('')
    except Exception:
        pass
    parser = argparse.ArgumentParser(description="MCP工具：PPTX单页结构化解析与资源导出")
    parser.add_argument('--input', '-i', required=True, help='输入PPTX文件路径')
    parser.add_argument('--output', '-o', default='output', help='输出文件夹路径')
    parser.add_argument('--log', default='ERROR', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], help='日志级别')
    parser.add_argument('--img-quality', type=int, default=95, help='图片导出质量（1-100）')
    parser.add_argument('--godot-advice', action='store_true', help='是否生成Godot适配建议')
    parser.add_argument('--page', type=int, help='要解析的幻灯片页码（从1开始）')
    args = parser.parse_args()

    if not os.path.isfile(args.input):
        log_print(f"[错误] 输入文件不存在: {args.input}")
        sys.exit(1)

    from pptx import Presentation
    prs = Presentation(args.input)
    prs.pptx_path = args.input  # 强制加上真实路径
    page_count = len(prs.slides)
    if args.page:
        if not (1 <= args.page <= page_count):
            log_print(f"[错误] 页码超出范围，当前PPT共{page_count}页。")
            sys.exit(1)
        slide_idx = args.page - 1
    else:
        slide_idx = ask_slide_index(page_count)
    log_print(f"[信息] 将解析第{slide_idx+1}页幻灯片...")

    # 自动生成唯一输出目录
    slide_num = slide_idx + 1
    out_dir = make_unique_output_dir(args.output, args.input, slide_num)
    img_dir = os.path.join(out_dir, 'images')
    txt_dir = os.path.join(out_dir, 'texts')
    tbl_dir = os.path.join(out_dir, 'tables')
    layout_dir = os.path.join(out_dir, 'layouts')
    md_path = os.path.join(out_dir, '核心说明.md')

    # 解析PPTX单页
    parsed = parse_slide(prs, slide_idx)

    # 调试：打印图片资源解析结果
    log_print(f"[调试] 解析后图片数量: {len(parsed.get('images', []))}")
    for idx, img in enumerate(parsed.get('images', [])):
        log_print(f"[调试] 图片{idx+1}: name={img.get('name')}, type={type(img)}, keys={list(img.keys())}, has_image={'image' in img}, image_type={type(img.get('image', None)) if 'image' in img else None}")

    # 增加页面大小信息
    slide_width = prs.slide_width
    slide_height = prs.slide_height
    parsed['slide_width'] = int(slide_width)
    parsed['slide_height'] = int(slide_height)

    # 修正版：递归处理命名，确保所有嵌套group内的shape都能加后缀
    def mark_shadow_in_name(elements):
        if not isinstance(elements, list):
            return
        for elem in elements:
            if not isinstance(elem, dict):
                continue
            has_runs = isinstance(elem.get('runs'), list)
            shadow = elem.get('shadow')
            visible = shadow.get('visible') if shadow else None
            print(f'[调试] name={elem.get("name")}, has_runs={has_runs}, shadow={shadow}, visible={visible}, visible_type={type(visible)}')
            if has_runs and shadow and visible:
                if 'name' in elem and '_含阴影' not in elem['name']:
                    print(f'[调试] 命名加后缀: {elem["name"]} -> {elem["name"] + "_含阴影"}')
                    elem['name'] += '_含阴影'
            children = elem.get('children')
            if isinstance(children, list):
                mark_shadow_in_name(children)

    # 集成点：导出布局前递归处理命名
    if 'layout' in parsed and 'elements' in parsed['layout']:
        mark_shadow_in_name(parsed['layout']['elements'])
        # 再次递归处理，确保生效
        mark_shadow_in_name(parsed['layout']['elements'])
        # 导出前强制打印所有元素的name
        def print_all_names(elements, level=0):
            for elem in elements:
                if isinstance(elem, dict):
                    print('  '*level + f'[导出前] name: {elem.get("name")}')
                    if 'children' in elem and isinstance(elem['children'], list):
                        print_all_names(elem['children'], level+1)
        print_all_names(parsed['layout']['elements'])

    # 导出资源
    log_print(f"[调试] 导出前图片数量: {len(parsed.get('images', []))}")
    images = export_images(parsed['images'], img_dir, slide_num, chinese_naming, args.img_quality)
    log_print(f"[调试] 导出后图片数量: {len(images)}")
    for idx, img in enumerate(images):
        log_print(f"[调试] 导出图片{idx+1}: name={img.get('name')}, path={img.get('path')}, meta_keys={list(img.get('meta', {}).keys())}, has_image={'image' in img.get('meta', {})}, image_type={type(img.get('meta', {}).get('image', None)) if 'image' in img.get('meta', {}) else None}")
    texts = export_texts(parsed['texts'], txt_dir, slide_num, chinese_naming)
    tables = export_tables(parsed['tables'], tbl_dir, slide_num, chinese_naming)
    layout_path = export_layout(parsed['layout'], layout_dir, slide_num, slide_width=int(slide_width), slide_height=int(slide_height))

    # 生成核心说明文档
    generate_core_md(md_path, images, texts, tables, layout_path, godot_advice=args.godot_advice, slide_width=int(slide_width), slide_height=int(slide_height))
    log_print(f"[完成] 资源已导出至: {out_dir}")


if __name__ == '__main__':
    main() 